#include <iostream>
using namespace std;
#include <string>

//函数对象（仿函数）
/*
 - 函数对象在使用时，可以像普通函数那样调用，可以有参数，可以有返回值
 - 函数对象超出普通函数的概念，函数对象可以有自己的状态
 - 函数对象可以作为参数传递
*/

// 1、函数对象在使用时，可以像普通函数那样调用，可以有参数，可以有返回值
class MyAdd
{
public:
    int operator()(int v1, int v2)
    {
        return v1 + v2;
    }
};

void test1()
{
    MyAdd myadd;
    cout << myadd(10, 90) << endl;
}

// 2、函数对象超出普通函数的概念，函数对象可以有自己的状态
class MyPrint
{
public:
    MyPrint()
    {
        this->count = 0;
    }
    
    void operator()(string test)
    {
        cout << test << endl;
        this->count++;
    }

    int count;//内部自己的状态
};

void test2()
{
    MyPrint myprint;
    myprint("Hello World");
    myprint("Hello World");
    myprint("Hello World");

    cout << "myprint调用次数为：" << myprint.count << endl;
}

// 3、函数对象可以作为参数传递
void doPrint(MyPrint& p, string test)
{
    p(test);
}

void test3()
{
    MyPrint myprint;
    doPrint(myprint, "C++");
}


int main()
{
    test1();
    test2();
    test3();
    
    return 0;
}